/* ----------------------------------------------------------------------
*
* Copyright (C) 2025 XiaoFei. All rights reserved.
*
* @file:		XiaoFei_Usart3.c
* @author:		XiaoFei
* @Date:     	13-January-2025
* @Revision: 	V1
* @Project: 	XiaoFei BSP Library
*
* -------------------------------------------------------------------- */

#include "stm32f4xx.h"
#include "XiaoFei_Usart3.h"
#include "stdio.h"
#include "stdarg.h"

/* 
* @function: 	Usart3_Init
*/
void Usart3_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Pin=Usart3_Pin_TX;
	GPIO_Init(Usart3_GPIO_TX,&GPIO_InitStructure);
	#ifdef Usart3_AddRx
		GPIO_InitStructure.GPIO_Pin=Usart3_Pin_RX;
		GPIO_Init(Usart3_GPIO_RX,&GPIO_InitStructure);
	#endif
		GPIO_PinAFConfig(Usart3_GPIO_TX,GPIO_PinSource10,GPIO_AF_USART3);
    #ifdef Usart3_AddRx
        GPIO_PinAFConfig(Usart3_GPIO_RX,GPIO_PinSource11,GPIO_AF_USART3);
    #endif
	USART_InitTypeDef USART_Initstructure;
	USART_Initstructure.USART_BaudRate=Usart3_BaudRate;
	USART_Initstructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    #ifdef Usart3_AddRx
        USART_Initstructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
    #else
        USART_Initstructure.USART_Mode=USART_Mode_Tx;
    #endif
	USART_Initstructure.USART_Parity=USART_Parity_No;
	USART_Initstructure.USART_StopBits=USART_StopBits_1;
	USART_Initstructure.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART3,&USART_Initstructure);
    #ifdef Usart3_AddRx
        NVIC_PriorityGroupConfig(USART3_Group);
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=USART3_ITPre;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=USART3_ITSub;
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
	    USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
    #endif
	USART_Cmd(USART3,ENABLE);
}

/* 
* @function: 	Usart3_SendByte
* @parameter:	[in] Byte					 The byte will be send.
*/
void Usart3_SendByte(unsigned char Byte)
{
    USART_SendData(USART3,Byte);
    while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET);
}

/* 
* @function: 	Usart3_SendString
* @parameter:	[in] String					 The String will be send.
*/
static void Usart3_SendString(char *String)
{
	for (unsigned int i=0; String[i]!='\0';i ++)
		Usart3_SendByte(String[i]);
}

/* 
* @function: 	Usart3_Printf
* @parameter:	[in] format					 The parameter will be send in Usart3_Printf.
*/
void Usart3_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	Usart3_SendString(String);
}

#ifdef Usart3_AddRx
/* 
* @function: 	Usart3_IRQHandler
* @callback:	The function will be callback when the Usart3 receive the data.
*/
void USART3_IRQHandler(void)
{
	if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET)
		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
#endif


